package com.atguigu.aclservice.helper;

import com.atguigu.aclservice.entity.Permission;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 根据权限数据构建菜单数据
 * </p>
 *
 * @author He Wentao
 * @since 2022/10/9 22:28
 */
public class PermissionHelper {

    /**
     * 使用递归方法建菜单
     * @param treeNodes
     * @return
     */
    public static List<Permission> build(List<Permission> treeNodes) {
        // 创建一个集合，用于保存拼接好的路由数组
        List<Permission> trees = new ArrayList<>();
        // 遍历传入的集合，获取到每一个 Permission 对象
        for (Permission treeNode : treeNodes) {

            // 判断 pid 是否为 0 ，也就是判断是不是第一层路由
            // 默认第一层路由，是一个数组，类似于 “树” 这种数据结构，0 是一个开始节点
            if ("0".equals(treeNode.getPid())) {

                // 如果 pid 是 0 ，则表示这个 Permission 对象为起始节点，设置 “层数” 为 1
                treeNode.setLevel(1);
                // 获取到 “开始节点” 之后，我们需要根据 “开始节点”的 id，查询到子节点，并拼接到 ”开始节点“ 的 Children 属性中去
                Permission children = findChildren(treeNode, treeNodes);
                // 将拼接好的 “树” 结构对象，存放到数组中去
                trees.add(children);
            }
        }
        return trees;
    }

    /**
     * 递归查找子节点
     * @param treeNodes
     * @return
     */
    public static Permission findChildren(Permission treeNode,List<Permission> treeNodes) {

        // 先创建一个集合，赋给一级路由，用于存储子路由
        treeNode.setChildren(new ArrayList<>());

        // 遍历传递过来的 总数据集合
        for (Permission it : treeNodes) {
            // 判断 开始节点的 id 和 当前对象的 pid 是否一样
            if(treeNode.getId().equals(it.getPid())) {
                // 如果一样，就增加一个层级
                int level = treeNode.getLevel() + 1;
                // 设置当前对象的层级为 “增加后的层级”
                it.setLevel(level);
                // 判断当前对象的 getChildren 是否为空，
                // 不为空，则表示数据库中存储了子路由
                if (treeNode.getChildren() == null) {
                    // 在创建一个数组，赋给 Children 属性
                    treeNode.setChildren(new ArrayList<>());
                }
                // 进行递归调用，拼接子路由到 Children 属性数组中去
                treeNode.getChildren().add(findChildren(it,treeNodes));
            }
        }
        return treeNode;
    }
}
